#include "LuaBase.h"

bool	__Result		= false;
int		ref_Frame		=0;
int		ref_Message		=0;
int		ref_Exit		=0;
int		ref_FocusLost	=0;
int		ref_FocusGain	=0;
lua_State* L;
bool __Frame()
{
	EnterCriticalSection(&G_CS);
	lua_rawgeti(L,LUA_REGISTRYINDEX, ref_Frame);
	lua_pushnumber(L,gge::Timer_GetDelta());
	lua_pushnumber(L,gge::Input_GetMousePosX());
	lua_pushnumber(L,gge::Input_GetMousePosY());
 	lua_call(L,3,1);
 	__Result = lua_toboolean(L,-1)? true : false;
 	lua_pop(L,1);
	LeaveCriticalSection(&G_CS);
	return __Result;
}
bool __Message(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	//if (NoWindow && uMsg == WM_STYLECHANGING && wParam == GWL_STYLE) { 
	//	STYLESTRUCT *StyleStruct = (STYLESTRUCT*)lParam; 
	//	StyleStruct->styleNew = WS_POPUP|WS_VISIBLE; 
	//} 
	EnterCriticalSection(&G_CS);
	lua_rawgeti(L,LUA_REGISTRYINDEX, ref_Message);
	lua_pushnumber(L,(long)hwnd);
	lua_pushnumber(L,(int)uMsg);
	lua_pushnumber(L,(int)wParam);
	lua_pushnumber(L,(long)lParam);
	lua_call(L,4,1);
	__Result = lua_toboolean(L,-1)? true : false;
	lua_pop(L,1);
	LeaveCriticalSection(&G_CS);
	return __Result;
}
bool __Exit()
{
	EnterCriticalSection(&G_CS);
	lua_rawgeti(L,LUA_REGISTRYINDEX, ref_Exit);
	lua_call(L,0,1);
	__Result = lua_toboolean(L,-1)? true : false;
	lua_pop(L,1);
	LeaveCriticalSection(&G_CS);
	return __Result;
}
bool __FocusLost()
{
	EnterCriticalSection(&G_CS);
	lua_rawgeti(L,LUA_REGISTRYINDEX, ref_FocusLost);
	lua_call(L,0,1);
	__Result = lua_toboolean(L,-1)? true : false;
	lua_pop(L,1);
	LeaveCriticalSection(&G_CS);
	return __Result;
}

bool __FocusGain()
{
	EnterCriticalSection(&G_CS);
	lua_rawgeti(L,LUA_REGISTRYINDEX, ref_FocusGain);
	lua_call(L,0,1);
	__Result = lua_toboolean(L,-1)? true : false;
	lua_pop(L,1);
	LeaveCriticalSection(&G_CS);
	return __Result;
}
//System
bool		LuaBase::Engine_Create(lua_State* ls){
	L=ls;
	return gge::Engine_Create();
}
bool		LuaBase::System_Initiate(){
	IsInit = true;
	return gge::System_Initiate();
}
bool		LuaBase::System_Start(){
	return gge::System_Start();
}
void		LuaBase::System_Stop(){
	IsExit = true;
}
void		LuaBase::Engine_Release(){
	return gge::Engine_Release();
}
void		LuaBase::System_SetStateCHAR(int state ,const char *value){
	gge::System_SetState(gge::GGE_STATE_CHAR(state),value);
}
void		LuaBase::System_SetStateINT(int state ,int value){
	gge::System_SetState(gge::GGE_STATE_INT(state),value);
}
void		LuaBase::System_SetStateBOOL(int state ,bool value){
	gge::System_SetState(gge::GGE_STATE_BOOL(state),value);
}
void		LuaBase::System_SetStateFUN(int state){
	switch(state)
	{ 
		case 0:gge::System_SetState(gge::GGE_FRAMEFUNC, __Frame);
			ref_Frame = luaL_ref(L, LUA_REGISTRYINDEX);
			break;
		case 1:gge::System_SetState(gge::GGE_EXITFUNC, __Exit);
			ref_Exit = luaL_ref(L, LUA_REGISTRYINDEX);
			break;
		case 2:gge::System_SetState(gge::GGE_FOCUSLOSTFUNC, __FocusLost);
			ref_FocusLost = luaL_ref(L, LUA_REGISTRYINDEX);
			break;
		case 3:gge::System_SetState(gge::GGE_FOCUSGAINFUNC, __FocusGain);
			ref_FocusGain = luaL_ref(L, LUA_REGISTRYINDEX);
			break;
		case 4:gge::System_SetState(gge::GGE_MESSAGEFUNC, __Message);
			ref_Message = luaL_ref(L, LUA_REGISTRYINDEX);
			break;
	}
}
const char* LuaBase::System_GetStateCHAR(int state ){
	return gge::System_GetState(gge::GGE_STATE_CHAR(state));
}
int			LuaBase::System_GetStateINT(int state ){
	return gge::System_GetState(gge::GGE_STATE_INT(state));
}
bool		LuaBase::System_GetStateBOOL(int state){
	return gge::System_GetState(gge::GGE_STATE_BOOL(state));
}
int			LuaBase::System_GetStateSYS(){
	return (int)gge::System_GetState(gge::GGE_STATE_SYS_VAL(0));
}
void		LuaBase::System_Log(const char *format){
	gge::System_Log(format);
}
bool		LuaBase::System_Launch(const char *url){
	return gge::System_Launch(url);
}
//Ini
void		LuaBase::Ini_SetFile(const char *v){
	gge::Ini_SetFile(v);
}
void		LuaBase::Ini_SetString(const char *section, const char *name, const char *value){
	gge::Ini_SetString(section,name,value);
}
const char* LuaBase::Ini_GetString(const char *section, const char *name, const char *value){
	return gge::Ini_GetString(section,name,value);
}
//Timer
UINT		LuaBase::Timer_GetTime(){
	return gge::Timer_GetTime ();
}
UINT		LuaBase::Timer_GetTick(){
	return gge::Timer_GetTick ();
}
float		LuaBase::Timer_GetDelta(){
	return gge::Timer_GetDelta ();
}
int			LuaBase::Timer_GetFPS(){
	return gge::Timer_GetFPS ();
}
//Random
UINT		LuaBase::Random_Create(){
	return gge::Random_Create ();
}
void		LuaBase::Random_Seed(int seed, UINT rid){
	gge::Random_Seed (seed,rid);
}
int			LuaBase::Random_Int(int min, int max, UINT rid){
	return gge::Random_Int(min,max,rid);
}
float		LuaBase::Random_Float(float min, float max, UINT rid){
	return gge::Random_Float(min,max,rid);
}
//Graph
void		LuaBase::Graph_Clear(UINT color){
	gge::Graph_Clear (color);
}
bool		LuaBase::Graph_BeginScene(void* Texture){
	return gge::Graph_BeginScene ((gge::ggeTexture *)Texture);
}
void		LuaBase::Graph_EndScene(){
	gge::Graph_EndScene ();
}
void		LuaBase::Graph_GetRenderTarget(void* Texture){
	gge::Graph_GetRenderTarget ((gge::ggeTexture *)Texture);
}
void		LuaBase::Graph_SetCurrentShader(void* Shader){
	gge::Graph_SetCurrentShader ((gge::ggeShader *)Shader);
}
void*		LuaBase::Graph_GetCurrentShader(){
	return gge::Graph_GetCurrentShader ();
}
void		LuaBase::Graph_RenderLine(float x1, float y1, float x2, float y2, UINT color){
	gge::Graph_RenderLine (x1,y1,x2,y2,color);
}
void		LuaBase::Graph_RenderRect(float x1, float y1, float x2, float y2, UINT color){
	gge::Graph_RenderRect (x1,y1,x2,y2,color);
}
void LuaBase::Graph_RenderTriple(void* triple){
	gge::Graph_RenderTriple (*(gge::ggeTriple*)triple);
}
void LuaBase::Graph_RenderQuad(void* quad){
	gge::Graph_RenderQuad (*(gge::ggeQuad*)quad);
}
//void		LuaBase::Graph_SetClipping(int x, int y, int width, int height){
//	gge::Graph_SetClipping (x,y,width,height);
//}
//void		LuaBase::Graph_SetTransform(float x, float y, float dx, float dy, float rot, float hscale, float vscale){
//	gge::Graph_SetTransform (x,y,dx,dy,rot,hscale,vscale);
//}
void LuaBase::Graph_Snapshot(const char *filename,int format){
	gge::Graph_Snapshot (filename,gge::GGE_IMAGE_FORMAT(format));
}
void LuaBase::Graph_RenderBatch(UINT primType, void* vt, int primNum,void* tex, int blend ){
	gge::Graph_RenderBatch(gge::PRIM_TYPE(primType),(gge::ggeVertex*)vt,primNum,(gge::ggeTexture*)tex,blend);
}
void LuaBase::Graph_RenderBatchIndices(UINT primType, void* vt, int vertexNum, void* indices, int primNum, void* tex, int blend){
	gge::Graph_RenderBatchIndices(gge::PRIM_TYPE(primType),(gge::ggeVertex*)vt,vertexNum,(USHORT*)indices,primNum,(gge::ggeTexture*)tex,blend);
}
//Input

float LuaBase::Input_GetMousePosX(){
	return gge::Input_GetMousePosX ();
}
float LuaBase::Input_GetMousePosY(){
	return gge::Input_GetMousePosY ();
}
void LuaBase::Input_SetMousePos(float x, float y){
	gge::Input_SetMousePos (x,y);
}
int LuaBase::Input_GetMouseWheel(){
	return gge::Input_GetMouseWheel ();
}
bool		LuaBase::Input_IsMouseOver(){
	return gge::Input_IsMouseOver ();
}
bool		LuaBase::Input_IsKeyPress(int key){
	return gge::Input_IsKeyPress (key);
}
bool		LuaBase::Input_IsKeyUp(int key){
	return gge::Input_IsKeyUp (key);
}
bool		LuaBase::Input_IsKeyDown(int key){
	return gge::Input_IsKeyDown (key);
}
bool		LuaBase::Input_IsMousePress(int key){
	return gge::Input_IsMousePress (key);
}
bool		LuaBase::Input_IsMouseUp(int key){
	return gge::Input_IsMouseUp (key);
}
bool		LuaBase::Input_IsMouseDown(int key){
	return gge::Input_IsMouseDown (key);
}
int			LuaBase::Input_GetKey(){
	return gge::Input_GetKey ();
}
const char * LuaBase::Input_GetChar(){
	return gge::Input_GetChar ();
}
const char * LuaBase::Input_GetKeyName(int key){
	return gge::Input_GetKeyName (key);
}

//Resource
void		LuaBase::Resource_Load(const char *filename,lua_State* L){
	size_t size;
	char* data = gge::Resource_Load(filename,&size);
	if (data)
	{
		lua_pushlstring(L,data,size);
		gge::Resource_Free(data);
	}else
		lua_pushnil(L);
}
UINT		LuaBase::Resource_GetSize(const char *filename){
	return gge::Resource_GetSize(filename);
}
bool		LuaBase::Resource_IsExist(const char *filename){
	return gge::Resource_IsExist(filename);
}
void		LuaBase::Resource_Free(void* res){
	gge::Resource_Free((char*)res);
}
UINT		LuaBase::Resource_LoadTo(const char *filename,void* buf,UINT size){
	return gge::Resource_LoadTo(filename,(char*)buf,size);
}
bool		LuaBase::Resource_AttachPack(const char *filename, const char *password){
	return gge::Resource_AttachPack(filename,password);
}
void		LuaBase::Resource_RemovePack(const char *filename){
	gge::Resource_RemovePack(filename);
}
void		LuaBase::Resource_AddPath(const char *filename){
	gge::Resource_AddPath(filename);
}

int REG_GGE_Base(lua_State * L){

	const char* gname = "__ggeBase";

	ELuna::registerClass<LuaBase>(L, gname, ELuna::constructor<LuaBase>);

	ELuna::registerMethod<LuaBase>(L, "Engine_Create",			&LuaBase::Engine_Create);
	//ELuna::registerMethod<ggeBase>(L, "Engine_Release", &ggeBase::Engine_Release);
	ELuna::registerMethod<LuaBase>(L, "System_Initiate",		&LuaBase::System_Initiate);
	ELuna::registerMethod<LuaBase>(L, "System_Stop",			&LuaBase::System_Stop);
	ELuna::registerMethod<LuaBase>(L, "System_SetStateINT",		&LuaBase::System_SetStateINT);
	ELuna::registerMethod<LuaBase>(L, "System_SetStateBOOL",	&LuaBase::System_SetStateBOOL);
	ELuna::registerMethod<LuaBase>(L, "System_SetStateCHAR",	&LuaBase::System_SetStateCHAR);
	ELuna::registerMethod<LuaBase>(L, "System_SetStateFUN",		&LuaBase::System_SetStateFUN);
	
	ELuna::registerMethod<LuaBase>(L, "System_GetStateINT",		&LuaBase::System_GetStateINT);
	ELuna::registerMethod<LuaBase>(L, "System_GetStateBOOL",	&LuaBase::System_GetStateBOOL);
	ELuna::registerMethod<LuaBase>(L, "System_GetStateCHAR",	&LuaBase::System_GetStateCHAR);
	ELuna::registerMethod<LuaBase>(L, "System_GetStateSYS",		&LuaBase::System_GetStateSYS);
	ELuna::registerMethod<LuaBase>(L, "System_Log",				&LuaBase::System_Log);
	ELuna::registerMethod<LuaBase>(L, "System_Launch",			&LuaBase::System_Launch);

	ELuna::registerMethod<LuaBase>(L, "Resource_Load",			&LuaBase::Resource_Load,1);
	ELuna::registerMethod<LuaBase>(L, "Resource_LoadTo",		&LuaBase::Resource_LoadTo);
	ELuna::registerMethod<LuaBase>(L, "Resource_GetSize",		&LuaBase::Resource_GetSize);
	ELuna::registerMethod<LuaBase>(L, "Resource_IsExist",		&LuaBase::Resource_IsExist);
	//ELuna::registerMethod<LuaBase>(L, "Resource_Free",			&LuaBase::Resource_Free);
	
	ELuna::registerMethod<LuaBase>(L, "Resource_AttachPack",	&LuaBase::Resource_AttachPack);
	ELuna::registerMethod<LuaBase>(L, "Resource_RemovePack",	&LuaBase::Resource_RemovePack);
	ELuna::registerMethod<LuaBase>(L, "Resource_AddPath",		&LuaBase::Resource_AddPath);

	ELuna::registerMethod<LuaBase>(L, "Ini_SetFile",			&LuaBase::Ini_SetFile);
	ELuna::registerMethod<LuaBase>(L, "Ini_SetString",			&LuaBase::Ini_SetString);
	ELuna::registerMethod<LuaBase>(L, "Ini_GetString",			&LuaBase::Ini_GetString);

	ELuna::registerMethod<LuaBase>(L, "Timer_GetTime",			&LuaBase::Timer_GetTime);
	ELuna::registerMethod<LuaBase>(L, "Timer_GetTick",			&LuaBase::Timer_GetTick);
	ELuna::registerMethod<LuaBase>(L, "Timer_GetDelta",			&LuaBase::Timer_GetDelta);
	ELuna::registerMethod<LuaBase>(L, "Timer_GetFPS",			&LuaBase::Timer_GetFPS);

	ELuna::registerMethod<LuaBase>(L, "Random_Seed",			&LuaBase::Random_Seed);
	ELuna::registerMethod<LuaBase>(L, "Random_Int",				&LuaBase::Random_Int);
	ELuna::registerMethod<LuaBase>(L, "Random_Float",			&LuaBase::Random_Float);

	ELuna::registerMethod<LuaBase>(L, "Graph_Clear",			&LuaBase::Graph_Clear);
	ELuna::registerMethod<LuaBase>(L, "Graph_BeginScene",		&LuaBase::Graph_BeginScene);
	ELuna::registerMethod<LuaBase>(L, "Graph_EndScene",			&LuaBase::Graph_EndScene);
	ELuna::registerMethod<LuaBase>(L, "Graph_GetRenderTarget",	&LuaBase::Graph_GetRenderTarget);
	ELuna::registerMethod<LuaBase>(L, "Graph_SetCurrentShader", &LuaBase::Graph_SetCurrentShader);
	ELuna::registerMethod<LuaBase>(L, "Graph_GetCurrentShader", &LuaBase::Graph_GetCurrentShader);
	ELuna::registerMethod<LuaBase>(L, "Graph_RenderLine",		&LuaBase::Graph_RenderLine);
	ELuna::registerMethod<LuaBase>(L, "Graph_RenderRect",		&LuaBase::Graph_RenderRect);
	ELuna::registerMethod<LuaBase>(L, "Graph_RenderTriple",		&LuaBase::Graph_RenderTriple);
	ELuna::registerMethod<LuaBase>(L, "Graph_RenderQuad",		&LuaBase::Graph_RenderQuad);
	//ELuna::registerMethod<LuaBase>(L, "Graph_SetClipping",		&LuaBase::Graph_SetClipping);
	//ELuna::registerMethod<LuaBase>(L, "Graph_SetTransform",		&LuaBase::Graph_SetTransform);
	ELuna::registerMethod<LuaBase>(L, "Graph_Snapshot",			&LuaBase::Graph_Snapshot);
	ELuna::registerMethod<LuaBase>(L, "Graph_RenderBatch",		&LuaBase::Graph_RenderBatch);
	ELuna::registerMethod<LuaBase>(L, "Graph_RenderBatchIndices", &LuaBase::Graph_RenderBatchIndices);
	//ELuna::registerMethod<ggeBase>(L, "Graph_SetProjectionMatrix", &ggeBase::Graph_SetProjectionMatrix);
	//ELuna::registerMethod<ggeBase>(L, "Graph_GetProjectionMatrix", &ggeBase::Graph_GetProjectionMatrix);
	//ELuna::registerMethod<ggeBase>(L, "Graph_SetViewMatrix", &ggeBase::Graph_SetViewMatrix);
	//ELuna::registerMethod<ggeBase>(L, "Graph_GetViewMatrix", &ggeBase::Graph_GetViewMatrix);

	ELuna::registerMethod<LuaBase>(L, "Input_GetMousePosX",		&LuaBase::Input_GetMousePosX);
	ELuna::registerMethod<LuaBase>(L, "Input_GetMousePosY",		&LuaBase::Input_GetMousePosY);
	ELuna::registerMethod<LuaBase>(L, "Input_SetMousePos",		&LuaBase::Input_SetMousePos);
	ELuna::registerMethod<LuaBase>(L, "Input_GetMouseWheel",	&LuaBase::Input_GetMouseWheel);
	ELuna::registerMethod<LuaBase>(L, "Input_IsMouseOver",		&LuaBase::Input_IsMouseOver);
	ELuna::registerMethod<LuaBase>(L, "Input_IsKeyPress",		&LuaBase::Input_IsKeyPress);
	ELuna::registerMethod<LuaBase>(L, "Input_IsKeyUp",			&LuaBase::Input_IsKeyUp);
	ELuna::registerMethod<LuaBase>(L, "Input_IsKeyDown",		&LuaBase::Input_IsKeyDown);
	ELuna::registerMethod<LuaBase>(L, "Input_IsMousePress",		&LuaBase::Input_IsMousePress);
	ELuna::registerMethod<LuaBase>(L, "Input_IsMouseUp",		&LuaBase::Input_IsMouseUp);
	ELuna::registerMethod<LuaBase>(L, "Input_IsMouseDown",		&LuaBase::Input_IsMouseDown);
	ELuna::registerMethod<LuaBase>(L, "Input_GetKey",			&LuaBase::Input_GetKey);
	ELuna::registerMethod<LuaBase>(L, "Input_GetChar",			&LuaBase::Input_GetChar);
	ELuna::registerMethod<LuaBase>(L, "Input_GetKeyName",		&LuaBase::Input_GetKeyName);

	return 1;
}
